home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 398 / 398.xpi / chrome / forecastfox.jar / content / ping / ping-service.js next >
Text File  |  2010-02-04  |  11KB  |  363 lines

  1. /*------------------------------------------------------------------------------
  2.   Copyright (c) 2008 Ensolis, LLC. All Rights Reserved.
  3.   ----------------------------------------------------------------------------*/
  4.  
  5. /******************************************************************************
  6.  * Ping Constants
  7.  *****************************************************************************/
  8. const RUN_INSTALL = Ci.ffIPingService.RUN_INSTALL;
  9. const RUN_UPGRADE = Ci.ffIPingService.RUN_UPGRADE;
  10. const RUN_UNINSTALL = Ci.ffIPingService.RUN_UNINSTALL;
  11.  
  12. /******************************************************************************
  13.  * Interfaces used monitor upgrade, install, uninstall process and
  14.  * notify the server when changes occur.
  15.  * 
  16.  * @status    FROZEN
  17.  * @version   1.0
  18.  ******************************************************************************/
  19. function PingService() 
  20. {
  21.   //setup additional interfaces
  22.   this._ifaces.push(Ci.nsIObserver);
  23.   this._ifaces.push(Ci.nsISupportsWeakReference);
  24.   
  25.   //setup a new error
  26.   this._error = Cc["@ensolis.com/forecastfox/error-item;1"].
  27.                 createInstance(Ci.ffIErrorItem);        
  28. }
  29. PingService.prototype = {
  30.   __proto__: new ServiceBase("PingService"),
  31.   _obSvc: null,
  32.   _checkTimer: null,
  33.   
  34.   ////////////////////////////
  35.   // nsIObserver 
  36.   observe: function PingService_observe(aSubject, aTopic, aData) 
  37.   {
  38.     // check the interval on timer callback
  39.     if (aTopic == "timer-callback") {
  40.       this._checkInterval();
  41.       return;
  42.     }
  43.     
  44.     //only do something if item is us
  45.     var item = aSubject.QueryInterface(Ci.nsIUpdateItem);
  46.     if (item.id != "{0538E3E3-7E9B-4d49-8831-A227C80A7AD3}")
  47.       return;
  48.     
  49.     //get the migrator service
  50.     var mgrSvc = Cc["@ensolis.com/forecastfox/manager-service;1"].
  51.                  getService(Ci.ffIManagerService);
  52.     var migSvc = mgrSvc.migrator;
  53.         
  54.     //determine action based on message  
  55.     switch (aData) {
  56.         
  57.     //being upgraded
  58.     case "item-upgraded":
  59.         
  60.       //going to version less than tracked
  61.       if (migSvc.compare(item.version, "0.7") < 0)
  62.         this._send(RUN_UNINSTALL, "0.9.10", "*");
  63.       break;
  64.           
  65.     //being uninstalled
  66.     case "item-uninstalled":
  67.       this._send(RUN_UNINSTALL, "0.9.10", "*"); 
  68.       break;
  69.         
  70.     //being cancelled
  71.     case "item-cancel-action":
  72.       this.run();
  73.       break;
  74.     }
  75.   },
  76.  
  77.   ////////////////////////////////
  78.   // ffIService  
  79.   
  80.   /**
  81.    * Initialize the component.  Called by the manager service.
  82.    */  
  83.   start: function PingService_start()
  84.   {            
  85.     //get extension manager
  86.     var exMgr = Cc["@mozilla.org/extensions/manager;1"].
  87.                 getService(Ci.nsIExtensionManager);
  88.     
  89.     // do our ping tracking
  90.     this._checkInterval();
  91.     
  92.     // start the check timer
  93.     this._checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
  94.     this._checkTimer.init(this, 10*ONE_MINUTE, Ci.nsITimer.TYPE_REPEATING_SLACK);  
  95.     
  96.     //add observer
  97.     this._obSvc = Cc["@mozilla.org/observer-service;1"].
  98.                   getService(Ci.nsIObserverService);        
  99.     this._obSvc.addObserver(this, "em-action-requested", false);
  100.     
  101.     //return success
  102.     return true;
  103.   },
  104.   
  105.   /**
  106.    * Destroy the component.  Called by the manager service.  This may be
  107.    * called prior to start so it needs to be safe.
  108.    */  
  109.   stop: function PingService_stop()
  110.   {
  111.     //unregister from the observer service
  112.     this._obSvc.removeObserver(this, "em-action-requested");
  113.     
  114.     // stop the check timer
  115.     this._checkTimer.cancel();
  116.     this._checkInterval();
  117.     
  118.     //remove image references
  119.     for (id in AccuTrack.images) {
  120.       image = AccuTrack.images[id];
  121.       image.onload = null;
  122.       image.parentNode.removeChild(image);      
  123.       delete AccuTrack.images[id];
  124.     }
  125.       
  126.     //remove variables
  127.     this._obSvc = null;
  128.     this._checkTimer = null;
  129.   },
  130.                 
  131.   ////////////////////////////////
  132.   // ffIPingService  
  133.     
  134.   /**
  135.    * Run ping command.
  136.    */  
  137.   run: function PingService_run()
  138.   {
  139.     //get preferences
  140.     var pinged = getPref("pinged");
  141.     var migrated = getPref("migrated");
  142.           
  143.     //use migrated value if pinged is blank
  144.     if (pinged == "" && migrated != "")
  145.       pinged = migrated;
  146.     
  147.     //determine ping command and send
  148.     switch (pinged) {
  149.     
  150.       //same version do nothing
  151.       case "0.9.10":
  152.         break;
  153.         
  154.       //never installed or previously uninstalled.    
  155.       case "":
  156.       case "*":
  157.         this._send(RUN_INSTALL, "", "0.9.10");
  158.         break;
  159.         
  160.       //upgrading from old version
  161.       default:       
  162.         this._send(RUN_UPGRADE, pinged, "0.9.10");
  163.         break;
  164.     }
  165.   },
  166.   
  167.   /**
  168.    * Function for tracking ui events.  This method has the same signature as
  169.    * the Google Analytics Event Tracking.  This allows us to implement that
  170.    * functionality in the future if we need it.
  171.    *
  172.    * @param   The category of the event.
  173.    * @param   The action to track.
  174.    * @param   Optional label for the event.
  175.    * @param   Optional value for the event.
  176.    */ 
  177.   trackEvent: function PingService_trackEvent(category, action, label, value) {
  178.   
  179.     // pass on to accuweather gif tracking
  180.     AccuTrack.push(category, action, label, value);
  181.     
  182.     // any other type of tracking
  183.   },
  184.   
  185.   /**
  186.    * Pass a url to our internal trackers where the only thing that needs
  187.    * updates is the random value in the url.
  188.    *
  189.    * @param   The url to track.
  190.    */
  191.   trackURL: function PingService_trackURL(url) {
  192.     
  193.     // pass on to accuweather gif tracking
  194.     AccuTrack.url(url);
  195.     
  196.     // any other type of tracking    
  197.   },
  198.   
  199.   ////////////////////////////
  200.   // Internal Functions 
  201.   
  202.   /**
  203.    * Build query string and send request.
  204.    *
  205.    * @param   Type of ping command to perform.
  206.    * @param   Version we are coming from.
  207.    * @param   Version we are going to.
  208.    */    
  209.   _send: function PingService__send(aType, aFrom, aTo)
  210.   {
  211.     //create query url
  212.     var query = "http://forecastfox.ensolis.com/logs/log.php"; 
  213.     var guid = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
  214.     query += "?type=" + aType;
  215.     query += "&from=" + aFrom;
  216.     query += "&to=";
  217.     query += (aTo == "*") ? "" : aTo;
  218.     query += "&guid=" + guid;
  219.     
  220.     //send ping request    
  221.     
  222.     var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
  223.                   createInstance(Ci.nsIXMLHttpRequest);      
  224.     request.open("GET", query, true);
  225.     
  226.     //update channel priority - toolkit 1.5 or greater
  227.     if ("nsISupportsPriority" in Ci) {
  228.       if (request.channel instanceof Ci.nsISupportsPriority)
  229.         request.channel.priority = Ci.nsISupportsPriority.PRIORITY_HIGHEST;
  230.     }
  231.     request.send(null);  
  232.     
  233.     //set pref as to version
  234.     setPref("pinged", aTo);
  235.     
  236.     //log the ping in the errors.log for help debugging.  
  237.     var mgrSvc = Cc["@ensolis.com/forecastfox/manager-service;1"].
  238.                  getService(Ci.ffIManagerService);
  239.     var dskSvc = mgrSvc.disk;
  240.     switch (aType) {
  241.     case RUN_INSTALL:
  242.       dskSvc.log("Installing version " + aTo + " on " + guid, null, null);
  243.       break;
  244.     case RUN_UNINSTALL:
  245.       dskSvc.log("Uninstalling version " + aFrom + " on " + guid, null, null);
  246.       break;
  247.     case RUN_UPGRADE:
  248.       dskSvc.log("Upgrading version " + aFrom + " to " + aTo + " on " + guid, 
  249.                  null, null);
  250.       break;
  251.     }
  252.   },
  253.   
  254.   _checkInterval: function PingService__checkInterval() {
  255.     var now = Math.round(Date.now() / 1000);
  256.  
  257.     var daily = getPref("pinged.daily");
  258.     var weekly = getPref("pinged.weekly");
  259.     var monthly = getPref("pinged.monthly");
  260.     
  261.     // do daily ping
  262.     if ((now - daily > ONE_DAY/1000) || (now - daily < 0)) {
  263.       this.trackEvent("active", "users", "daily");
  264.       setPref("pinged.daily", now);
  265.     }
  266.     
  267.     // do weekly ping
  268.     if ((now - weekly > ONE_WEEK/1000) || (now - weekly < 0)) {
  269.       this.trackEvent("active", "users", "weekly");
  270.       setPref("pinged.weekly", now);      
  271.     }
  272.     
  273.     // do monthly ping
  274.     if ((now - monthly > ONE_MONTH/1000) || (now - monthly < 0)) {
  275.       this.trackEvent("active", "users", "monthly");
  276.       setPref("pinged.monthly", now);      
  277.     }    
  278.   }
  279. };
  280.  
  281. /*******************************************************************************
  282.  * Object to do the gif based accuweather tracking.  The push method is called
  283.  * from trackEvent with all the same parameters.  We lowercase the params and
  284.  * join them with a "-".  This is used as a key to lookup the image that needs
  285.  * loaded.  A random id is generated and the image is stored via that id.  
  286.  * On the image load event the pop method is called with the image id and it is
  287.  * removed from hash of stored images.
  288.  ******************************************************************************/
  289. var AccuTrack = {
  290.   images: {},
  291.   keys: {
  292.     "tooltip-load-swa": "QXA3515",
  293.     "tooltip-load-radar": "QXA3516",
  294.     "tooltip-load-cc": "QXA3517",
  295.     "tooltip-load-dayt": "QXA3518",
  296.     "tooltip-load-dayf": "QXA3519",
  297.     "tooltip-click-radar": "QXA3520",
  298.     "active-users-monthly": "QXA3521",
  299.     "active-users-weekly": "QXA3522",
  300.     "active-users-daily": "QXA3523"
  301.   },
  302.   
  303.   push: function accutrack_push(category, action, label, value) {
  304.     var url_format="http://spotlight.accuweather.com/dyndoc/spotlight/adc_$key/index/flasher.gif?cbs=$id";
  305.     
  306.     // determine the key
  307.     var parts = [category, action, label, value];
  308.     var key = parts.filter(function(a) { return (a) ? true : false; }).join("-");
  309.     
  310.     // if the key doesn't exist return early
  311.     if (!this.keys.hasOwnProperty(key))
  312.       return;
  313.     
  314.     // build the url
  315.     var id = (new Date()).getTime();
  316.     var url = url_format.replace("$key", this.keys[key]);
  317.     url = url.replace("$id", id);
  318.     LOG("forecastfox ping: " + url);
  319.  
  320.     
  321.     // setup the image and store it in the hash
  322.     var self = this;
  323.     this.images[id] = this._createImage();
  324.     this.images[id].onload = function() { self.pop(id); };
  325.     this.images[id].src = url;
  326.   },
  327.   
  328.   pop: function accutrack_pop(id) {
  329.     if (!this.images.hasOwnProperty(id))
  330.       return;
  331.     var image = this.images[id];
  332.     image.onload = null;
  333.     image.parentNode.removeChild(image);
  334.     delete this.images[id];
  335.   },
  336.   
  337.   url: function accutrack__url(url) {
  338.     
  339.     // build the url
  340.     var id = (new Date()).getTime();
  341.     var new_url = url.replace("RANDOM", id);
  342.     LOG("forecastfox ping: " + new_url);
  343.  
  344.     
  345.     // setup the image and store it in the hash
  346.     var self = this;
  347.     this.images[id] = this._createImage();
  348.     this.images[id].onload = function() { self.pop(id); };
  349.     this.images[id].src = new_url;
  350.   },
  351.   
  352.   _createImage: function accutrack__createImage() {
  353.     var main = getMainWindow();
  354.     var doc = main.document;
  355.     
  356.     var image = doc.createElement("image");
  357.     image.setAttribute("collapsed", "true");
  358.     
  359.     var root = doc.documentElement;
  360.     root.appendChild(image);
  361.     return image;
  362.   }
  363. };